package com.uduemc.biso.node.web.interceptor;

import com.uduemc.biso.core.extities.center.Agent;
import com.uduemc.biso.core.extities.center.AgentLoginDomain;
import com.uduemc.biso.core.extities.center.AgentNodeServerDomain;
import com.uduemc.biso.core.extities.center.SysServer;
import com.uduemc.biso.core.extities.pojo.ICP35;
import com.uduemc.biso.core.utils.AgentLinkUtil;
import com.uduemc.biso.node.core.entities.HDomain;
import com.uduemc.biso.node.web.component.RequestHolder;
import com.uduemc.biso.node.web.component.SpringContextUtils;
import com.uduemc.biso.node.web.config.SpringContextUtil;
import com.uduemc.biso.node.web.entities.AccessAgent;
import com.uduemc.biso.node.web.entities.AccessHost;
import com.uduemc.biso.node.web.exception.NotFoundDomainException;
import com.uduemc.biso.node.web.exception.NotFoundDomainICPException;
import com.uduemc.biso.node.web.service.byfeign.AgentService;
import com.uduemc.biso.node.web.service.byfeign.DomainService;
import com.uduemc.biso.node.web.service.byfeign.ServerService;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 针对域名是否备案的拦截器 通过拦截获取域名备案的数据信息访问的过滤
 *
 * @author guanyi
 */
@Component
public class IcpInterceptor implements HandlerInterceptor {

    @Resource
    private RequestHolder requestHolder;

    @Resource
    private SpringContextUtil springContextUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        request.setAttribute("SESSION_ID", request.getSession().getId());
        ServerService serverServiceImpl = SpringContextUtils.getBean("serverServiceImpl", ServerService.class);
        DomainService domainServiceImpl = SpringContextUtils.getBean("domainServiceImpl", DomainService.class);
        AgentService agentServiceImpl = SpringContextUtils.getBean("agentServiceImpl", AgentService.class);
        SysServer sysServer = serverServiceImpl.selfSysServer();
        if (sysServer == null) {
            throw new NotFoundDomainICPException("未知的服务器信息！");
        }
        requestHolder.set(sysServer);

        String domain = request.getServerName();

        AccessHost accessHost = new AccessHost();
        accessHost.setDomain(domain);
        requestHolder.set(accessHost);

        AccessAgent accessAgent = new AccessAgent();
        requestHolder.set(accessAgent);

        // 如果是开发环境且访问域名为 localhost 则直接放行
        if (springContextUtil.local() && domain.toLowerCase().equals("localhost")) {
            return true;
        }

        ICP35 icp35 = null;
        HDomain hDomain = null;
        // 如果是香港、美国等不需要备案的服务器，直接放行
        if (sysServer.getIicp() != null && sysServer.getIicp().intValue() == 0) {
            // 如果是通过次控端后台域名访问站点端，则 HDomain 数据可以为空。
            if (sysServer.getDomain().equals(domain)) {
                return true;
            }
            // 从数据库中获取到该域名数据
            hDomain = domainServiceImpl.getInfoByDomainName(domain);
            if (hDomain == null) {
                // 通过域名获取到代理商信息，如果能获取到则说么是代理商域名访问，如果获取不到则说明是非站内域名
                AgentNodeServerDomain agentNodeServerDomain = agentServiceImpl.agentNodeServerDomainByDomainName(domain);
                if (agentNodeServerDomain != null) {
//					icp35 = domainServiceImpl.getCacheIcpDomain(domain, true);
//					if (icp35 == null) {
//						// 抛出异常，没有找到域名的ICP信息
//						throw new NotFoundDomainICPException(domain + " 的ICP信息未能获取到！");
//					}
//					accessHost.setIcp(icp35);
                    return true;
                }
                String twoDomain = domain.substring(domain.indexOf(".") + 1);
                String code = domain.substring(0, domain.indexOf("."));
                agentNodeServerDomain = agentServiceImpl.agentNodeServerDomainByUniversalDomainName(twoDomain);
                if (agentNodeServerDomain != null) {
                    hDomain = domainServiceImpl.getInfoByDomainName(code + "." + sysServer.getDomain());
                    if (hDomain != null) {
                        String agentNodeDefaultDomain = AgentLinkUtil.agentNodeDefaultDomain(code, agentNodeServerDomain);
                        if (agentNodeDefaultDomain.equals(domain)) {
                            hDomain.setDomainName(domain);
                            Agent agent = agentServiceImpl.agent(agentNodeServerDomain.getAgentId());
                            AgentLoginDomain agentLoginDomain = agentServiceImpl.agentLoginDomain(agentNodeServerDomain.getAgentId());
                            accessAgent.setAgentDomain(true).setAgent(agent).setAgentLoginDomain(agentLoginDomain)
                                    .setAgentNodeServerDomain(agentNodeServerDomain);
//							icp35 = domainServiceImpl.getCacheIcpDomain(domain, true);
                        }
                    }
                }
            }

            if (hDomain == null) {
                // 抛出没有找到域名的异常
                throw new NotFoundDomainException(domain + " 系统中不存在该域名！");
            }

            accessHost.setHDomain(hDomain);
            // 无须备案
//			accessHost.setIcp(icp35);
            return true;
        }

        // 如果是通过次控端后台域名访问站点端，则 HDomain 数据可以为空，只要判断是否备案便可。
        if (sysServer.getDomain().equals(domain)) {
            icp35 = domainServiceImpl.getCacheIcpDomain(domain);
            if (icp35 == null) {
                icp35 = domainServiceImpl.getIcpDomain(domain);
            }
            if (icp35 == null) {
                // 抛出异常，没有找到域名的ICP信息
                throw new NotFoundDomainICPException(domain + " 的ICP信息未能获取到（1）！");
            }
            if (icp35.getResult() != 1) {
                // 抛出异常，没有找到域名的ICP信息
                throw new NotFoundDomainICPException("获取到 " + domain + " 的ICP信息，备案未通过（1）！");
            }
            accessHost.setIcp(icp35);
            return true;
        }

        // 通过域名找到对应的 HDomain 数据，如果为找到，则拦截在外，不允许访问。
        hDomain = domainServiceImpl.getInfoByDomainName(domain);
        if (hDomain != null) {
            // 获取备案信息
            icp35 = domainServiceImpl.getCacheIcpDomain(hDomain);
            if (icp35 == null) {
                if (hDomain.getDomainType() != null && hDomain.getDomainType().shortValue() == (short) 0) {
                    icp35 = domainServiceImpl.getIcpDomain(domain);
                }
            }
        } else {
            // 通过域名获取到代理商信息，如果能获取到则说么是代理商域名访问，如果获取不到则说明是非站内域名
            AgentNodeServerDomain agentNodeServerDomain = agentServiceImpl.agentNodeServerDomainByDomainName(domain);
            if (agentNodeServerDomain != null) {
                icp35 = domainServiceImpl.getCacheIcpDomain(domain);
                if (icp35 == null) {
                    // 如果缓存中不存在，则同步获取备案数据信息
                    icp35 = domainServiceImpl.getIcpDomain(domain);
                }
                if (icp35 == null) {
                    // 抛出异常，没有找到域名的ICP信息
                    throw new NotFoundDomainICPException(domain + " 的ICP信息未能获取到（2）！");
                }
                if (icp35.getResult() != 1) {
                    // 抛出异常，没有找到域名的ICP信息
                    throw new NotFoundDomainICPException("获取到 " + domain + " 的ICP信息，备案未通过（2）！");
                }
                accessHost.setIcp(icp35);
                return true;
            }
            String twoDomain = domain.substring(domain.indexOf(".") + 1);
            String code = domain.substring(0, domain.indexOf("."));
            agentNodeServerDomain = agentServiceImpl.agentNodeServerDomainByUniversalDomainName(twoDomain);
            if (agentNodeServerDomain != null) {
                hDomain = domainServiceImpl.getInfoByDomainName(code + "." + sysServer.getDomain());
                if (hDomain != null) {
                    String agentNodeDefaultDomain = AgentLinkUtil.agentNodeDefaultDomain(code, agentNodeServerDomain);
                    if (agentNodeDefaultDomain.equals(domain)) {
                        hDomain.setDomainName(domain);
                        Agent agent = agentServiceImpl.agent(agentNodeServerDomain.getAgentId());
                        AgentLoginDomain agentLoginDomain = agentServiceImpl.agentLoginDomain(agentNodeServerDomain.getAgentId());
                        accessAgent.setAgentDomain(true).setAgent(agent).setAgentLoginDomain(agentLoginDomain).setAgentNodeServerDomain(agentNodeServerDomain);
                        icp35 = domainServiceImpl.getCacheIcpDomain(domain);
                        if (icp35 == null) {
                            // 如果缓存中不存在，则同步获取备案数据信息
                            icp35 = domainServiceImpl.getIcpDomain(domain);
                        }
                    }
                }
            }
        }

        if (hDomain == null) {
            // 抛出没有找到域名的异常
            throw new NotFoundDomainException(domain + " 系统中不存在该域名！");
        }
        if (icp35 == null) {
            // 抛出异常，没有找到域名的ICP信息
            throw new NotFoundDomainICPException(domain + " 的ICP信息未能获取到！（3）");
        }
        if (icp35.getResult() != 1) {
            // 抛出异常，没有找到域名的ICP信息
            throw new NotFoundDomainICPException("获取到 " + domain + " 的ICP信息，备案未通过（3）！");
        }

        accessHost.setHDomain(hDomain);
        accessHost.setIcp(icp35);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        requestHolder.clean();
    }
}
